﻿using FySystem.Data.OrmA.Formatter;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Text;

namespace FySystem.Data.OrmA
{
    /// <summary>
    /// 数据库类型（不再支持OracelAccess.dll，改为Managed.OracelAccess.dll）
    /// </summary>
    public enum DbTypes
    {
        Oracle, Mysql, Sqlserver, PostgreSQL, SQLite
    }

    /// <summary>
    /// 主键类型
    /// </summary>
    public enum PrimaryKeyTypes
    {
        AutoIncremental,
        Sequence,
        GUID,
        Custom, 
        //这个是SQL server中的GUID
        GUIDN
    }

    public class FyDbContext
    {
        /// <summary>
        /// 所有的数据库连接
        /// </summary>
        private static Dictionary<string, DbConfigs> _dbConnections = new Dictionary<string, DbConfigs>();

        #region 初始化
        /// <summary>
        /// 添加单个数据库连接
        /// </summary>
        /// <param name="dbType">数据库类型</param>
        /// <param name="providerFactory">数据库提供工厂</param>
        /// <param name="connStr">数据库连接字符串</param>
        public static void AddDbConnection(DbTypes dbType, DbProviderFactory providerFactory, string connStr)
        {
            try
            {
                AddDbConnection("", dbType, providerFactory, connStr);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 添加数据库连接，如果只有一个连接，则flag可以不传
        /// </summary>
        /// <param name="flag">数据库连接标记，在调用GetSession()时，如果有多个连接；或者只有一个连接，但flag在创建的时候不是用的默认值，则需要传入对应的flag参数</param>
        /// <param name="dbType">数据库类型</param>
        /// <param name="providerFactory">数据库提供程序</param>
        /// <param name="connStr">数据库连接字符串</param>
        public static void AddDbConnection(string flag, DbTypes dbType, DbProviderFactory providerFactory, string connStr)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(flag))
                    flag = "fy";

                ISqlFormatter formatter = null;
                switch (dbType)
                {
                    case DbTypes.Oracle: formatter = new OracleFormatter(); break;
                    case DbTypes.Sqlserver: formatter = new SqlFormatter(); break;
                    case DbTypes.Mysql: formatter = new MysqlFormatter(); break;
                    case DbTypes.PostgreSQL: formatter = new NpgsqlFormatter(); break;
                    case DbTypes.SQLite: formatter = new SQLiteFormatter(); break;
                    default: throw new Exception("不支持的数据库类型~");
                }

                DbConfigs dbConfigs = new DbConfigs(formatter, providerFactory, connStr);
                _dbConnections.Add(flag, dbConfigs);
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

        #region 创建连接
        /// <summary>
        /// 获取默认连接，即flag="fy"的连接
        /// </summary>
        /// <param name="withTransaction">是否启用事务</param>
        /// <returns></returns>
        public static DBSession GetDBSession(bool withTransaction = false)
        {
            try
            {
                return GetDBSession("fy", withTransaction);
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 根据flag获取连接
        /// </summary>
        /// <param name="flag">数据库flag</param>
        /// <param name="withTransaction">是否启用事务</param>
        /// <returns></returns>
        public static DBSession GetDBSession(string flag, bool withTransaction = false)
        {
            DBSession res = null;
            try
            {
                if (_dbConnections.ContainsKey(flag) == false)
                    throw new Exception("flag对应的数据库不存在~");

                DbConfigs dbConfigs = _dbConnections[flag];
                res = new DBSession(dbConfigs);
                res.Open();

                if (withTransaction)
                    res.BeginTransaction();
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }
        #endregion
    }
}
